package tiny.soft.com.common.util;


import org.apache.commons.collections.CollectionUtils;
import tiny.soft.com.common.exception.BusinessException;

import java.lang.reflect.Method;
import java.util.*;

/**
 * 集合操作util
 * @author latiao
 */
public class CollectionUtil extends CollectionUtils {

    /**
     * 交集
     */
    public static <T> List<T> setRetain(List<T> maskOne, List<T> maskTwo) {
        Set<T> set = new HashSet<>();
        set.addAll(maskOne);
        set.retainAll(maskTwo);
        return new ArrayList<>(set);
    }

    /**
     * 差集
     */
    public static <T> List<T> setRemove(List<T> maskOne, List<T> maskTwo){
        Set<T> set = new HashSet<>();
        set.addAll(maskOne);
        set.removeAll(maskTwo);
        return new ArrayList<>(set);
    }

    /**
     * 补集
     */
    public static <T> List<T> setRepair(List<T> maskOne, List<T> maskTwo){
        List<T> retain = setRetain(maskOne, maskTwo);
        // 减去交集
        List<T> remove = setRemove(maskOne, retain);
        return new ArrayList<>(remove);
    }

    /**
      * 数据分组，将list集合按照item中的某个属性的值进行分组
      * @Author 宋晓虎
      * @Date 2019/9/5 09:05:23
      * @param list 分组集合
      * @param fieldName 属性名称
      * @param class1 list集合的class类型
      * @return java.util.Map<java.lang.String,java.util.List<T>>
    **/
    public static <T> Map<String, List<T>> groupList(List<T> list, String fieldName, Class<T> class1) {
        Map<String, List<T>> retMap = new HashMap<String, List<T>>();
        if (CollectionUtil.isEmpty(list)) {
            return retMap;
        }
        //根据属性得到方法名称
        Class<T> clazz=class1;
        String method="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
        Method execMethod= null;
        try {
            execMethod = clazz.getDeclaredMethod(method);
            List<T> mapList = null;
            for (T t1 : list) {
                String key =(String)execMethod.invoke(t1);//根据流出地址分组
                mapList = retMap.get(key);
                if (mapList == null) {
                    mapList = new ArrayList<T>();
                    mapList.add(t1);
                    retMap.put(key, mapList);
                } else {
                    mapList.add(t1);
                }
            }
            return retMap;

        } catch (Exception e) {
            throw (BusinessException)new BusinessException("416","数据转换异常",true).initCause(e);
        }
    }

    /**
     * 此方法具有特殊性，仅用于按照行政区划编码分组并且区划编码需要补充到12位
     * 例如实体中的编码值为1301，那种执行此方法1301会补充8个0，变成130100000000
     * @Author 宋晓虎
     * @Date 2019/9/5 09:05:23
     * @param list 分组集合
     * @param fieldName 属性名称
     * @param class1 list集合的class类型
     * @return java.util.Map<java.lang.String,java.util.List<T>>
     **/
    public static <T> Map<String, List<T>> groupListAddZero(List<T> list, String fieldName, Class<T> class1) throws Throwable {
        Map<String, List<T>> retMap = new HashMap<String, List<T>>();
        if (CollectionUtil.isEmpty(list)) {
            return retMap;
        }
        //根据属性得到方法名称
        Class<T> clazz=class1;
        String method="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
        Method execMethod= null;
        try {
            execMethod = clazz.getDeclaredMethod(method);
            List<T> mapList = null;
            for (T t1 : list) {
                String key =(String)execMethod.invoke(t1);//根据流出地址分组
                mapList = retMap.get(StringUtil.addZero(key));
                if (mapList == null) {
                    mapList = new ArrayList<T>();
                    mapList.add(t1);
                    retMap.put(StringUtil.addZero(key), mapList);
                } else {
                    mapList.add(t1);
                }
            }
            return retMap;

        } catch (Exception e) {
            throw new BusinessException("416","数据转换List TO Map 异常",true).initCause(e);
        }
    }
}
